package qianting.news.auth.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import qianting.news.auth.dto.LoginDto;
import qianting.news.auth.entity.NewsUser;
import qianting.news.auth.service.NewsUserService;
import qianting.news.auth.utils.JwtUtil;
import qianting.news.common.entity.State;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "鉴权管理")
@RequestMapping("/")
@RestController
@Slf4j
public class AuthController {

    @Autowired
    private NewsUserService newsUserService;

    @ApiOperation(value = "登录")
    @PostMapping("login")
    @SentinelResource(value = "loginResource", blockHandler = "resourceHandler", blockHandlerClass = AuthController.class)
    public State login(@RequestBody @Validated LoginDto loginDto) {

        String username = loginDto.getUsername();
        String password = loginDto.getPassword();
        NewsUser newsUser = newsUserService.getUserPasswordAndId(username);
        Assert.notNull(newsUser, "该用户不存在");//断言该用户不为空
        String pswd_md5 = DigestUtil.sha256Hex(password + newsUser.getSalt());
        if (!pswd_md5.equals(newsUser.getPassword())) return State.fail("用户名或密码错误");
        //执行到这里说明登录成功

        //生成jwt
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", username);
        map.put("userId", newsUser.getId());
        String token = JwtUtil.genToken(map);
        return State.succ(token);

    }

    @ApiOperation(value = "注册")
    @PostMapping("register")
    @SentinelResource(value = "registerResource", blockHandler = "resourceHandler", blockHandlerClass = AuthController.class)
    public State register(@RequestBody @Validated LoginDto loginDto) {

        String username = loginDto.getUsername();
        String password = loginDto.getPassword();
        NewsUser newsUser = newsUserService.getUserPasswordAndId(username);
        Assert.isNull(newsUser);

        newsUser = new NewsUser();
        newsUser.setName(username);
        String salt = RandomUtil.randomString(3);
        newsUser.setPassword(DigestUtil.sha256Hex(password + salt));
        newsUser.setSalt(salt);
        newsUserService.saveUser(newsUser);

        //运行到这里说明已经执行
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", loginDto.getUsername());
        map.put("userId", newsUser.getId());
        String token = JwtUtil.genToken(map);
        return State.succ(token);

    }

    @ApiOperation(value = "验证")
    @GetMapping("verify")
    @SentinelResource(value = "verifyResource", blockHandler = "resourceHandler", blockHandlerClass = AuthController.class)
    public State verify(@RequestHeader("token") String token) {

        Map<String, Object> claims = JwtUtil.parseToken(token);
        return State.succ("登录成功", claims);

    }

    @ApiOperation(value = "刷新token")
    @GetMapping("refresh")
    @SentinelResource(value = "refreshResource", blockHandler = "resourceHandler", blockHandlerClass = AuthController.class)
    public State refresh(@RequestHeader("token") String token) {

        Map<String, Object> claims = JwtUtil.parseToken(token);
        String s = JwtUtil.genToken(claims);
        return State.succ("登录成功", s);

    }

    /**
     * 限流后续操作方法
     *
     * @param e
     * @return
     */
    public static State resourceHandler(String token, BlockException e) {
        String msg = "不好意思，前方拥挤，请您稍后再试";
        log.error(msg);
        return State.fail(msg);
    }

}
